#include <iostream>
using namespace std;

template <class T>
void f1(T &t)
{
    cout << "left value" << endl;
}
template <class T>
void f1(T &&t)
{
    cout << "right value" << endl;
}

template <class T>
void NotPerfectForward(T &&t)
{
    cout << "NotPerfectForward" << endl;
    f1(t); // 变量t的本质是左值，为啥？因为有名字了，叫t，可以取地址...
}
template <class T>
void PerfectForward(T &&t)
{
    cout << "PerfectForward" << endl;
    f1(std::forward<T>(t)); //用std::forward来把t转发为传递的左值/右值
}

void test() // perfect forwarding
{
    int a = 3;            //显然a是个左值
    NotPerfectForward(a); // left value
    //这里就不是完美转发，a已经move成了右值，但是在传给NotPerfectForward时
    //又变成左值了，因为参数t是个有名字，可以取地址，其本质是个左值。
    NotPerfectForward(std::move(a)); // left value
    NotPerfectForward(4);            // left value

    PerfectForward(a);            // left value
    PerfectForward(std::move(a)); // right value
    PerfectForward(4);            // right value
}

int main(int argc, char const *argv[])
{
    test();
    return 0;
}
